package com.pwt.security;

import com.pwt.entity.Role;
import com.pwt.entity.User;
import com.pwt.repository.MenuRepository;
import com.pwt.repository.RoleRepository;
import com.pwt.repository.UserRepository;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.pwt.security.JWTConstants.ROLE_PREFIX;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    private UserRepository userRepository;

    private RoleRepository roleRepository;

    private MenuRepository menuRepository;

    /**
     * 构造器注入
     *
     * @param userRepository
     * @param roleRepository
     * @param menuRepository
     */
    public UserDetailsServiceImpl(UserRepository userRepository, RoleRepository roleRepository, MenuRepository menuRepository) {
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.menuRepository = menuRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        Set<Role> roleSet = roleRepository.findByUsername(username);

        Set<String> grantedMenu = menuRepository.findGrantedMenuByUsername(username);
        List<String> authorities = new ArrayList<>();
        for (Role role : roleSet) {
            authorities.add(ROLE_PREFIX + role.getSign());
        }
        for (String menu : grantedMenu) {
            if (StringUtils.isNotBlank(menu)) {
                authorities.add(menu);
            }

        }
        user.setLastLoginTime(new Date());
        userRepository.save(user);
        return org.springframework.security.core.userdetails.User.builder()
                .username(user.getUsername())
                .password("$2a$10$uDxYWWctRi76OtqbGfWWD.B0VGpoCZpd3n.N12WakRnCqY/9bKNzG")
//                .password(user.getPassword())
                .authorities(authorities.toArray(new String[authorities.size()]))
                .build();
    }


    public String getToken(String username){
        UserDetails userDetails = loadUserByUsername(username);
        Map<String, Object> claims = new HashMap<>();
        claims.put("authorities",userDetails.getAuthorities());
        String token = Jwts.builder()
                .setSubject(userDetails.getUsername())
                .addClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000))
                .signWith(SignatureAlgorithm.HS512, JWTConstants.SECRET)
                .compact();
        return "Bearer " + token;
    }

}